package com.ping.study.service.tx;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ping.study.mapper.GamesMapper;
import com.ping.study.mapper.UrlsMapper;
import com.ping.study.model.dto.tx.LiveInfoRequest;
import com.ping.study.model.vo.live.LiveInfoResponse;
import com.ping.study.pojo.Games;
import com.ping.study.utils.tx.CKeyGenerator;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class LiveInfoService {

    private final WebClient webClient;
    private final CKeyGenerator cKeyGenerator;
    @Autowired
    private GamesMapper gamesMapper;
    @Autowired
    private UrlsMapper urlsMapper;
    @Autowired
    private TxSportTokenRefreshService txSportTokenRefreshService;;

    private StringRedisTemplate stringRedisTemplate;

    public LiveInfoService(@Qualifier("tencentWebClient")WebClient webClient, CKeyGenerator cKeyGenerator, StringRedisTemplate stringRedisTemplate) {
        this.webClient = webClient;
        this.cKeyGenerator = cKeyGenerator;
        this.stringRedisTemplate = stringRedisTemplate;
    }

    // 2. 远程调用时拼接 Cookie
    public String getCookieForRequest() throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
// 读取
        String cookieJson = stringRedisTemplate.opsForValue().get("tx_sports_cookie_map");
        Map<String, String> cookieMap = objectMapper.readValue(cookieJson, new TypeReference<>() {});
        return buildCookieHeader(cookieMap);
    }

    public String getLiveInfo(String cnlid) throws Exception {
        //先调用刷新cookie
        txSportTokenRefreshService.refreshCookies();
        Thread.sleep(100);
        String platform = "40201";
        String ckey = cKeyGenerator.generateCKey(cnlid, platform);

        // 1. 打印请求参数
        String queryParams = String.format(
                "ckey=%s&encrypt_ver=%s&platform=%s&tm=%d&cnlid=%s",
                ckey,
                LiveInfoRequest.generateEncryptVer(DayOfWeek.from(LocalDate.now())),
                platform,
                Instant.now().getEpochSecond(),
                cnlid
        );
        log.info("请求参数: {}", queryParams);

        // 2. 打印请求头（Cookie）
        String cookie = getCookieForRequest();
//        log.info("请求头 Cookie: {}", cookie);

        // 3. 发起请求
        String res = webClient.get()
                .uri(uriBuilder -> uriBuilder
                        .path("/cgi-bin/getliveinfo")
                        .queryParam("ckey", ckey)
                        .queryParam("encrypt_ver", LiveInfoRequest.generateEncryptVer(
                                DayOfWeek.from(LocalDate.now())))
                        .queryParam("platform", platform)
                        .queryParam("tm", Instant.now().getEpochSecond())
                        .queryParam("cnlid", cnlid)
                        .queryParam("defn","fhd")
                        .queryParam("ufps","auto")
                        .build())
                .header("Cookie", cookie)
                .retrieve()
                .bodyToMono(String.class)
                .block();

        List<String> list = extractPlayUrls(res);
        log.info("提取到的播放URL: {}", list);
        return res;
    }

    private String buildCookieHeader(Map<String, String> cookieMap) {
        return cookieMap.entrySet().stream()
                .map(e -> e.getKey() + "=" + e.getValue())
                .collect(Collectors.joining("; "));
    }

    public List<String> extractPlayUrls(String liveInfoJson) throws Exception {
        ObjectMapper mapper = new ObjectMapper();

        // 首先将JSON字符串解析为Map结构
        Map<String, Object> responseMap = mapper.readValue(liveInfoJson, new TypeReference<Map<String, Object>>() {});

        List<String> urls = new ArrayList<>();

        // 检查play_list是否存在
        if (responseMap.containsKey("play_list")) {
            List<Map<String, Object>> playList = (List<Map<String, Object>>) responseMap.get("play_list");

            for (Map<String, Object> playItem : playList) {
                // 检查urls是否存在
                if (playItem.containsKey("urls")) {
                    List<String> itemUrls = (List<String>) playItem.get("urls");
                    urls.addAll(itemUrls);
                }
            }
        }
        log.info("提取到的播放URL数量: {}", urls.size());
        return urls;
    }

    public String refreshLiveInfo() throws Exception {
        List<Games> gamesList = gamesMapper.selectAll();
        for (Games games : gamesList) {
            String playId = games.getPlayId();
            String liveInfo = getLiveInfo(playId);
            log.info("获取到的直播信息: {}", liveInfo);
            try {
                List<String> urls = extractPlayUrls(liveInfo);
                log.info("提取到的播放URL: {}", urls);
                urlsMapper.updateUrlsWithGameId(games.getGameId(), urls.get(urls.size()-1),"tx");
                urlsMapper.updateUrlsWithGameId(games.getGameId(), urls.get(0),"zb");
                // 这里可以保存urls到数据库或其他处理
            } catch (Exception e) {
                log.error("解析直播信息失败");
            }
        }
        return "刷新完成";
    }


}